package back;

/**
 * Clase que almacena la informacion necesaria para poder describir una 
 * celda y su posicion en el tablero. 
 */

public class Celda {

	private NoMovible noMov;
	private Movible mov;
	private Coordenada posicion;
	private Tablero tab;
	private boolean brilla=false;
	
	/**
	 * Constructor de la clase 
	 * @param coord coordenada de la celda.
	 */
	
	public Celda(Coordenada coord){
		this.posicion=coord;
	}
	
	/**
	 * Constructor de la clase 
	 * @param i fila de la celda.
	 * @param j columna de la celda.
	 * @param tablero 
	 */
	public Celda(int i, int j, Tablero tablero) {
		posicion= new Coordenada(i, j);
		tab=tablero;
	}
	
	/**
	 * Devuelve true si hay una caja en la celda
	 * o false en caso contrario. 
	 * @return boolean.
	 */
	public boolean hayCaja(){
		return (mov.getClass()==Caja.class);
	}
	
	/**
	 * Setea la variable noMov.
	 * @param NoMovible noMov parametro con el cual se va a setear la variable.
	 */
	public void setNoMovible(NoMovible noMov){
		this.noMov=noMov;
	}
	
	/**
	 * Setea la variable mov.
	 * @param Movible mov parametro con el cual se va a setear la variable.
	 */
	public void setMovible(Movible mov){
		this.mov=mov;
	}
	
	/**
	 * Pone a mov en la celda
	 * @param Movible mov
	 */
	
	public void pongoMovible(Movible mov){
		this.getNoMovible().pongoMov(this, mov);
	}
	
	/**
	 * Retorna la variable mov.
	 * @return Movible mov variable movible.
	 */
	public Movible getMovible(){
		return mov;
	}
	
	/**
	 * Retorna la variable noMov.
	 * @return NoMovible noMov variable noMovible.
	 */
	public NoMovible getNoMovible(){
		return noMov;
	}

	/**
	 * Devuelve la coordenada de la celda
	 * @return Coordenada retorna la posicion de la celda.
	 */
	public Coordenada getPosicion(){
		return this.posicion;
	}
	
	/**
	 * Retorna true o false de acuerdo a si la celda brilla o no
	 * @return boolean
	 */
	public boolean brilla(){
		return brilla;
	}
	
	/**
	 * Setea brilla en true y decrementa destinos restantes
	 */
	public void setBrilla(){
		this.brilla= true;
		tab.eliminaDestinosRest();
	}
	
	/**
	 * Setea brilla en false e incrementa destinos restantes
	 */
	
	public void setNoBrilla(){
		this.brilla= false;
		tab.agregaDestinosRest();
	}

	/**
	 * Devuelve true si es posible el movimiento en la direccion
	 * recibida como parametro, false en caso contrario. 
	 * @param int direccion del movimiento
	 * @return boolean.
	 */
	
	public boolean posibleMovida(int direccion) {
		Celda celdaDest=tab.getCelda(posicion.hacia(direccion));
		return(this.getNoMovible().posibleMov(direccion, celdaDest) &&
				this.getMovible().posibleMov(direccion, celdaDest));
		
	}
	
	/**
	 * Retorna la celda vecina con la direccion pasada como parametro 
	 * @return Celda
	 */
	
	public Celda getCeldaHacia(int direccion){
		return tab.getCelda(this.posicion.hacia(direccion));
	}

	/**
	 * Elimina a mov de la celda
	 */

	public void eliminaMov() {
		this.mov.eliminar(this);
		
	}
	
	/**
	 * Llama a gameOver
	 */
	
	public void muere(){
		tab.gameOver();
	}
		
	/**
	 * Retorna el tablero
	 */
	
	public Tablero getTablero(){
		return tab;
	}

	/**
	 * Agrega celda en la coordenada pasada como parametro
	 * @param Object celda
	 * @param Coordenada coord
	 */

	public void agrega(Object celda, Coordenada coord) {
		
		((Elemento)celda).agrego(this);
		
	}
	
}